package com.ruoyi.web.controller.ws;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.kaoyan.domain.EducationMessage;
import com.ruoyi.kaoyan.service.EducationMessageService;
import com.ruoyi.system.service.ISysUserService;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.timeout.IdleStateEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.MultiValueMap;
import org.yeauty.annotation.*;
import org.yeauty.pojo.Session;

import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author carpediem
 */
@ServerEndpoint(path = "/websocket/{userId}", port = "8080")
public class WebSocket {

    private Session session;

    @Autowired
    private ISysUserService userService;
    @Autowired
    private EducationMessageService messageService;

    /**
     * 用来记录sessionId和该session进行绑定
     */
    /*private static final Map<String, Session> MAP = new HashMap<>();*/
    private static final Map<Long, WebSocket> MAP = new ConcurrentHashMap<>();

    /**
     * 用来存放每个客户端对应的MyWebSocket对象
     */
    /*private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>();*/
    @BeforeHandshake
    public void handshake(Session session, HttpHeaders headers, @RequestParam String req, @RequestParam MultiValueMap reqMap, @PathVariable Long userId, @PathVariable Map pathMap) {
        session.setSubprotocols("stomp");
        if (StringUtils.isNull(userId)) {
            System.out.println("Authentication failed!");
            session.close();
        }
    }

    @OnOpen
    public void onOpen(Session session, HttpHeaders headers, @RequestParam String req, @RequestParam MultiValueMap reqMap, @PathVariable Long userId, @PathVariable Map pathMap) {
        /*String key = session.channel().id().toString();*/
        /*MAP.put(key, session);*/
        //加入set中
        /*webSocketSet.add(this);*/
        SysUser sysUser = userService.selectUserById(userId);
        String nickName = sysUser.getNickName();
        MAP.put(userId, this);
        System.out.println("有新连接加入:" + nickName + ",当前在线人数为" + MAP.size());
        session.sendText(nickName + "上线了(其频道号：" + userId + ")-->当前在线人数为：" + MAP.size());
        System.out.println("new connection");
        System.out.println(req);
    }

    @OnClose
    public void onClose(Session session, @PathVariable Long userId) {
        //从set中删除
        /*MAP.remove(session.channel().id().toString());*/
        MAP.remove(userId);
        System.out.println("有一连接关闭！当前在线人数为" + MAP.size());
        System.out.println("one connection closed");
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        throwable.printStackTrace();
    }

    @OnMessage
    public void onMessage(Session session, String message, @PathVariable Long userId) {
        String nickName = userService.selectUserById(userId).getNickName();
        System.out.println("来自客户端的消息-->" + nickName + ": " + message);
        //从客户端传过来的数据是json数据，所以这里使用jackson进行转换为SocketMsg对象，
        EducationMessage socketMsg = JSONUtil.toBean(message, EducationMessage.class);
        //单聊.需要找到发送者和接受者
        //发送者
        socketMsg.setSender(userId);
        String requestId = RandomUtil.randomNumbers(8);
        socketMsg.setRequestId(requestId);
        messageService.save(socketMsg);
        WebSocket fromSession = MAP.get(socketMsg.getSender());
        WebSocket toSession = MAP.get(socketMsg.getReceiver());
        //发送给接受者.
        if (toSession != null) {
            //发送给发送者.
            /*fromSession.sendText(nickname + "：" + socketMsg.getMsg());
            toSession.sendText(nickname + "：" + socketMsg.getMsg());*/
            fromSession.session.sendText(nickName + "：" + socketMsg.getContent());
            socketMsg.setIsRead("是");
            LambdaQueryWrapper<EducationMessage> eq = new LambdaQueryWrapper<EducationMessage>().eq(true, EducationMessage::getRequestId, requestId);
            Long messageId = messageService.getOne(eq).getId();
            socketMsg.setId(messageId);
            messageService.updateById(socketMsg);
            toSession.session.sendText(nickName + "：" + socketMsg.getContent());
        } else {
            //发送给发送者.
            /*fromSession.sendText("系统消息：对方不在线或者您输入的频道号不对");*/
            fromSession.session.sendText("系统消息：对方不在线或者您输入的频道号不对");
        }
        System.out.println(socketMsg);
        session.sendText("Hello IM!");
    }

    @OnBinary
    public void onBinary(Session session, byte[] bytes) {
        for (byte b : bytes) {
            System.out.println(b);
        }
        session.sendBinary(bytes);
    }

    @OnEvent
    public void onEvent(Session session, Object evt) {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
            switch (idleStateEvent.state()) {
                case READER_IDLE:
                    System.out.println("read idle");
                    break;
                case WRITER_IDLE:
                    System.out.println("write idle");
                    break;
                case ALL_IDLE:
                    System.out.println("all idle");
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 群发自定义消息
     */
    /*public void broadcast(String message) {
        for (WebSocket item : webSocketSet) {
            //同步异步说明参考：http://blog.csdn.net/who_is_xiaoming/article/details/53287691
            item.session.sendText(message);//异步发送消息.
        }
    }*/

}